using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Data.SqlClient;
using System.Linq;

namespace xiushen.Domain
{
    public interface IRepository{}
    
    public class Repository<TEntity> : ReadOnlyRepository<TEntity>
       
        where TEntity : EntityObject
    {

        public TEntity Persist(TEntity entity)
        {
            if (entity.EntityKey == null || entity.EntityKey.IsTemporary)
            {
                Insert(entity);
            }
            else
            {
                Update(entity);
            }
            return entity;
        }

        public T Persist<T>(T entity) where T : EntityObject
        {
            if (entity.EntityKey == null || entity.EntityKey.IsTemporary)
            {
                Insert(entity);
            }
            else
            {
                Update(entity);
            }
            return entity;
        }
        public void Insert<T>(T entity)
        {
            ObjectContext.AddObject(ObjectContext.GetEntitySet<T>().Name, entity);


            ObjectContext.SaveChanges();
        }

        public void Insert(TEntity entity)
        {
            ObjectContext.AddObject(ObjectContext.GetEntitySet<TEntity>().Name, entity);

            
            ObjectContext.SaveChanges();
        }

        public void Update(TEntity entity)
        {
            //WHY: This is a dirty hack to avoid Optimistic Concurrency Problems
            ObjectContext.Refresh(RefreshMode.ClientWins, entity);
            ObjectContext.SaveChanges();
            
        }
        public void Update<T>(T entity)
        {
            //WHY: This is a dirty hack to avoid Optimistic Concurrency Problems
            ObjectContext.Refresh(RefreshMode.ClientWins, entity);
            ObjectContext.SaveChanges();

        }
        public void Delete<T>(T entity)
        {
            ObjectContext.DeleteObject(entity);
            ObjectContext.SaveChanges();
        }
        public void Delete(TEntity entity)
        {
            ObjectContext.DeleteObject(entity);
            ObjectContext.SaveChanges();
        }

        public void Delete(IQueryable<TEntity> queryable)
        {
            foreach (var entity in queryable.ToList())
            {
                Delete(entity);
            }

        }
        public void Delete<T>(IQueryable<T> queryable)
        {
            foreach (var entity in queryable.ToList())
            {
                Delete(entity);
            }

        }
        public void Delete(short id)
        {
            var entity = Get(id);
            ObjectContext.DeleteObject(entity);
            ObjectContext.SaveChanges();
        }

        public void ExecuteNonQuery(string query, params object[] queryParameters)
        {
            try
            {
                ObjectContext.ExecuteStoreCommand(query, queryParameters);

            }
            catch (Exception ex)
            {

               throw new ApplicationException(query,ex);

            }
           

        }

        protected string GetSortExpression(string sortField, string defaultSortField, ResultSortDirection sortDirection)
        {
            return (string.IsNullOrEmpty(sortField) ? defaultSortField : sortField) + " " + ((sortDirection == ResultSortDirection.Ascending) ? "ASC" : "DESC");
        }
    }

}